package com.twb.core.cors;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

/** 
 * @ClassName CorsConfig 
 * @Description 跨域过滤器配置
 * @author DSY
 * @date 2018年10月28日 下午3:41:39 
 */ 
@Configuration
@ConfigurationProperties(prefix = "twb.cors")
@ConditionalOnProperty(name = { "twb.cors.enabled" }, havingValue = "true")
public class CorsConfig {

	private String mapping = "/**";
	
	private String allowedOrigins = "*";
	
	private String allowedMethods = "*";
	
	private String allowedHeaders = "*";
	
	private String exposedHeaders = HttpHeaders.SET_COOKIE;
	
	private Boolean allowCredentials = true;
	
	private Long maxAge = 3600L;
	
	private CorsConfiguration buildConfig() {  
        CorsConfiguration corsConfiguration = new CorsConfiguration();  
        // 1域名信息
        if(allowedOrigins.equals("*")) {
        	corsConfiguration.addAllowedOriginPattern(allowedOrigins);
        }else {
        	String[] orgins = allowedOrigins.split(",");
        	for (String orgin : orgins) {
        		corsConfiguration.addAllowedOrigin(orgin);
			}
        }
        // 2访问头信息
        if(allowedHeaders.equals("*")) {
        	corsConfiguration.addAllowedHeader(allowedHeaders); // 2允许任何头
        }else {
        	String[] headers = allowedHeaders.split(",");
        	for (String head : headers) {
        		corsConfiguration.addAllowedHeader(head);
			}
        }
        //3访问方法
        if(allowedMethods.equals("*")) {
        	corsConfiguration.addAllowedMethod(allowedMethods);
        }else {
        	String[] methods = allowedMethods.split(",");
        	for (String method : methods) {
        		corsConfiguration.addAllowedMethod(method.toUpperCase());
			}
        }
        //4暴露的头信息
        if(exposedHeaders.equals("*")) {
        	corsConfiguration.addExposedHeader(exposedHeaders);
        }else {
        	String[] headers = exposedHeaders.split(",");
        	for (String head : headers) {
        		corsConfiguration.addExposedHeader(head);
			}
        }
        //4允许Cookie跨域，在做登录校验的时候有用
        corsConfiguration.setAllowCredentials(allowCredentials);
        //预检请求的缓存时间（秒），即在这个时间段里，对于相同的跨域请求不会再预检了
        corsConfiguration.setMaxAge(maxAge);
        return corsConfiguration;  
    }  
  
     
    public CorsFilter corsFilter() {  
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();  
        source.registerCorsConfiguration(mapping, buildConfig()); //拦截访问路径 
        return new CorsFilter(source);  
    } 
    
    @Bean
    public FilterRegistrationBean<CorsFilter> corsFilterBean(){
    	FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<CorsFilter>(corsFilter());
		bean.setOrder(0);
		return bean;
    }
    
	public String getMapping() {
		return mapping;
	}
	public void setMapping(String mapping) {
		this.mapping = mapping;
	}
	public String getAllowedOrigins() {
		return allowedOrigins;
	}
	public void setAllowedOrigins(String allowedOrigins) {
		this.allowedOrigins = allowedOrigins;
	}
	public String getAllowedMethods() {
		return allowedMethods;
	}
	public void setAllowedMethods(String allowedMethods) {
		this.allowedMethods = allowedMethods;
	}
	public String getAllowedHeaders() {
		return allowedHeaders;
	}
	public void setAllowedHeaders(String allowedHeaders) {
		this.allowedHeaders = allowedHeaders;
	}
	public String getExposedHeaders() {
		return exposedHeaders;
	}
	public void setExposedHeaders(String exposedHeaders) {
		this.exposedHeaders = exposedHeaders;
	}
	public Boolean getAllowCredentials() {
		return allowCredentials;
	}
	public void setAllowCredentials(Boolean allowCredentials) {
		this.allowCredentials = allowCredentials;
	}
	public Long getMaxAge() {
		return maxAge;
	}
	public void setMaxAge(Long maxAge) {
		this.maxAge = maxAge;
	}
}
